package com.zslin.business.tools;

import com.zslin.business.dao.ICashOutDao;
import com.zslin.business.dao.ICashOutDetailDao;
import com.zslin.business.mini.dto.PayResultDto;
import com.zslin.business.mini.tools.PayTools;
import com.zslin.business.model.CashOut;
import com.zslin.business.model.CashOutDetail;
import com.zslin.business.wx.annotations.HasTemplateMessage;
import com.zslin.business.wx.annotations.TemplateMessageAnnotation;
import com.zslin.business.wx.tools.TemplateMessageTools;
import com.zslin.core.common.NormalTools;
import com.zslin.core.dao.IBaseAppConfigDao;
import com.zslin.core.dto.JsonValueDto;
import com.zslin.core.model.BaseAppConfig;
import com.zslin.core.tasker.ProcessTaskTools;
import com.zslin.core.tools.DateTools;
import com.zslin.core.tools.JsonTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 提现处理工具类
 */
@Component("cashOutTools")
@HasTemplateMessage
public class CashOutTools {

    @Autowired
    private ICashOutDao cashOutDao;

    @Autowired
    private ProcessTaskTools processTaskTools;

    @Autowired
    private IBaseAppConfigDao baseAppConfigDao;

    @Autowired
    private PayTools payTools;

    private static final Float MAX_MONEY = 200f; //单次转账最大金额

    @Autowired
    private ICashOutDetailDao cashOutDetailDao;

    @Autowired
    private SendTemplateMessageTools sendTemplateMessageTools;

    /**
     * 通过提现金额计算需要支付的次数
     * @param money 提现金额
     * @return
     */
    public Integer needPayAmount(Float money) {
        int amount = (int) (money/MAX_MONEY);
        float surplus = money%MAX_MONEY;
        return amount + (surplus>0?1:0);
    }

    /** 启动提现流程 */
    public void runCashOut(CashOut cashOut) {
        int period = 3600*24; //一次执行时间
//        int period = 30;
        //延迟10秒 转第一笔
        processTaskTools.buildCircleTask(cashOut.getAgentName()+"提现任务", "cashOutTools", "runPay",
                JsonTools.buildJsonString(new JsonValueDto("id", cashOut.getId())), buildTaskId(cashOut),
                DateTools.plusSeconds(10, "yyyy-MM-dd HH:mm:ss"), period, true);
    }

    /** 定时启动支付 */
    @Modifying
    @Transactional
    @TemplateMessageAnnotation(name = "返利到帐提醒", keys = "金额-时间")
    public void runPay(String params) {
        Integer id = JsonTools.getId(params);
        CashOut cashOut = cashOutDao.findOne(id);

        BaseAppConfig appConfig = baseAppConfigDao.loadOne();
        PayResultDto dto = null;
        if(appConfig!=null) {
            String taskId = buildTaskId(cashOut); //定时器ID
            float needPayMoney = buildPayMoney(cashOut.getSurplusMoney()); //需要支付的金额
            if(needPayMoney<=0) {
                processTaskTools.deleteTaskForce(taskId); return;
            }
            //如果小于等于0，不转款，但结束定时器

            CashOutDetail cod = new CashOutDetail();
            cod.setAgentId(cashOut.getAgentId());
            cod.setAgentName(cashOut.getAgentName());
            cod.setAgentOpenid(cashOut.getAgentOpenid());
            cod.setAgentPhone(cashOut.getAgentPhone());
            cod.setBatchNo(cashOut.getBatchNo());
            cod.setPayDay(NormalTools.curDate());
            cod.setPayLong(System.currentTimeMillis());
            cod.setPayTime(NormalTools.curDatetime());

            boolean isTest = false; //是否测试转款，true时则表示不真实转款
            //TODO 这里需要再次处理，返回处理结果到CashOut， 到账成功才下发通知
            dto = payTools.pay2User(buildPayNo(cashOut.getBatchNo()), cashOut.getAgentOpenid(),
                    appConfig.getAppName()+"-提现-"+ cashOut.getAgentName(), needPayMoney, isTest);
            if(PayResultDto.SUCCESS.equals(dto.getStatus())) { //支付成功
                cashOut.setStatus("1");

                cashOut.setSurplusMoney(cashOut.getSurplusMoney() - needPayMoney); //还剩余未支付的金额
                cashOut.setPaidMoney(cashOut.getPaidMoney() + needPayMoney); //已支付的金额
                cashOut.setPaidAmount(cashOut.getPaidAmount() + 1);
                cashOut.setSurplusAmount(cashOut.getSurplusAmount() - 1);

                float surplusMoney = cashOut.getSurplusMoney(); //转款成功后还剩余的金额
                cod.setPayMoney(needPayMoney);
                cod.setStatus("1");
                cod.setStatusReason("转款成功");
                cod.setSurplusMoney(cashOut.getSurplusMoney());

                sendTemplateMessageTools.send(cashOut.getAgentOpenid(), "返利到帐提醒", "", "你有一笔新的收款",
                        TemplateMessageTools.field("金额", needPayMoney + " 元"),
                        TemplateMessageTools.field("时间", cod.getPayTime()),

                        TemplateMessageTools.field(surplusMoney>0?"剩余金额将于明天同一时间继续转款给你":"本次提现申请已转款完毕"));

                // 如果剩余金额小于等于0，需要结束定时器
                if(surplusMoney<=0) {
                    cashOut.setStatus("2");
                    processTaskTools.deleteTaskForce(taskId);
                }
                cashOutDao.save(cashOut);
            } else {
                //cashOut.setStatus("0");
                cod.setStatusReason("0");
                cod.setStatusReason(dto.getErrCodeDes());
            }
            cashOutDetailDao.save(cod);
        }

    }

    /** 定时器ID */
    private String buildTaskId(CashOut cashOut) {
        return cashOut.getBatchNo()+"_"+cashOut.getId();
    }

    /** 生成支付的订单编号 */
    private String buildPayNo(String batchNo) {
        return batchNo+"T"+ NormalTools.getNow("yyyyMMddHHmm");
    }

    /** 生成需要实际支付的金额 */
    private float buildPayMoney(float money) {
        if(money>MAX_MONEY) {return MAX_MONEY;}
        else return money;
    }
}
